﻿//======================================================================
//
//        Copyright (C) 2011-2012 USAS
//        All rights reserved
//
//        filename : TextBoxEx.cs
//        description : 增强型TextBox, 增加输入控制
//
//        created by Jack Lu at 2011/12/9 13:00:44
//
//======================================================================

namespace Srvtools
{
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;

    public class InfoTextBoxEx : TextBox
    {
        #region 水印

        private const int WM_PAINT = 0xF;
        private bool isInitialized;

        /// <summary>
        /// 水印颜色, 默认深灰
        /// </summary>
        private Color _wateMarkColor = Color.DarkGray;

        /// <summary>
        /// 水印内容
        /// </summary>
        private string _waterMark;

        public string WaterMark
        {
            get { return _waterMark; }
            set { _waterMark = value; }
        }

        public Color WateMarkColor
        {
            get { return _wateMarkColor; }
            set { _wateMarkColor = value; }
        }

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == WM_PAINT)
            {
                WmPaint();
            }
        }

        private void WmPaint()
        {
            using (Graphics graphics = Graphics.FromHwnd(base.Handle))
            {
                if (Text.Length == 0
                    && !string.IsNullOrEmpty(_waterMark)
                    && !Focused)
                {
                    TextFormatFlags format =
                        TextFormatFlags.EndEllipsis |
                        TextFormatFlags.VerticalCenter;

                    if (RightToLeft == RightToLeft.Yes)
                    {
                        format |= TextFormatFlags.RightToLeft | TextFormatFlags.Right;
                    }

                    TextRenderer.DrawText(
                        graphics,
                        _waterMark,
                        Font,
                        base.ClientRectangle,
                        _wateMarkColor,
                        format);
                }
            }
        }

        #endregion

        #region 自动完成

        // 自动完成保存文件
        private string ContentFile;

        public InfoTextBoxEx()
        {
            this.AutoCompleteMode = AutoCompleteMode.Suggest;
            this.AutoCompleteSource = AutoCompleteSource.CustomSource;
        }

        /// <summary>   
        /// 控件创建的时候
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInvalidated(InvalidateEventArgs e)
        {
            base.OnInvalidated(e);

            if (isInitialized) return;

            isInitialized = true;

            Form form = FindForm();
            if (form != null)
            {
                ContentFile = Application.StartupPath + "\\" + CliUtils.fCurrentProject + "\\" +
                              form.GetType().Namespace + "." + form.Name + "." +
                              Name + ".txt";
            }

            GetItems();
        }

        /// <summary>
        /// 读取自动完成内容
        /// </summary>
        private void GetItems()
        {
            try
            {
                if (File.Exists(ContentFile) && AutoCompleteCustomSource.Count == 0)
                    AutoCompleteCustomSource.AddRange(File.ReadAllLines(ContentFile, Encoding.UTF8));
            }
            catch
            {
            }
        }

        /// <summary>
        /// 将自动完成项添加到文件
        /// </summary>
        private void AddToFile()
        {
            if (string.IsNullOrEmpty(ContentFile)) return;

            try
            {
                if (AutoCompleteCustomSource.Count == 0) return;

                var contents = new string[AutoCompleteCustomSource.Count];
                AutoCompleteCustomSource.CopyTo(contents, 0);
                File.WriteAllLines(ContentFile, contents, Encoding.UTF8);

                AutoCompleteCustomSource.Clear();
            }
            catch (Exception e)
            {

            }
        }

        /// <summary>
        /// 当离开控件时, 添加自动完成
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLeave(EventArgs e)
        {
            base.OnLeave(e);

            AddNewSuggestion();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            if (!base.Enabled)
                AddNewSuggestion();
        }

        /// <summary>
        /// 添加到自动提示里
        /// </summary>
        private void AddNewSuggestion()
        {
            if (!string.IsNullOrEmpty(base.Text)
                && AutoCompleteSource == AutoCompleteSource.CustomSource
                && !AutoCompleteCustomSource.Contains(base.Text))
            {
                var text = base.Text;
                AutoCompleteCustomSource.Add(base.Text);

                // 针对EEP
                base.Text = text;
            }
        }

        /// <summary>
        /// 控件释放时, 将内容写入文件
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            AddToFile();

            base.Dispose(disposing);
        }

        #endregion

        #region 输入限制

        /// <summary>
        /// 允许输入的类型
        /// <remarks>
        /// String: 默认, 允许所有输入
        /// </remarks>
        /// </summary>
        public enum InputType
        {
            String,
            Digit,
            Currency,
            Decimal,
            Float,
            Double,
            Short,
            Int,
            Long
        }

        private InputType _inputType = InputType.String;

        public InputType AllowedType
        {
            get { return _inputType; }
            set { _inputType = value; }
        }

        /// <summary>
        /// 检验是否为允许值
        /// </summary>
        /// <param name="val">输入值</param>
        /// <param name="inputType">允许的输入类型</param>
        /// <returns>是否通过验证</returns>
        private bool IsValid(string val, InputType inputType)
        {
            switch (inputType)
            {
                case InputType.Digit:
                    return Regex.IsMatch(val, @"^\d*$");
                case InputType.Currency:
                    decimal c;
                    if (!decimal.TryParse(val, out c))
                        return false;

                    int pos = val.IndexOf(".");
                    if (pos != -1)
                        return val.Substring(pos).Length <= 3;

                    return true;
                case InputType.Decimal:
                    decimal d;
                    return decimal.TryParse(val, out d);
                case InputType.Float:
                    float f;
                    return float.TryParse(val, out f);
                case InputType.Double:
                    double dl;
                    return double.TryParse(val, out dl);
                case InputType.Short:
                    short s;
                    return short.TryParse(val, out s);
                case InputType.Int:
                    int i;
                    return int.TryParse(val, out i);
                case InputType.Long:
                    long l;
                    return long.TryParse(val, out l);
                default:
                    return true;
            }
        }

        /// <summary>
        /// 处理粘贴事件
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys)Shortcut.CtrlV || keyData == (Keys)Shortcut.ShiftIns)
            {
                IDataObject iData = Clipboard.GetDataObject();
                if (iData != null)
                {
                    string newText = base.Text.Substring(0, base.SelectionStart)
                                     + (string)iData.GetData(DataFormats.Text)
                                     + base.Text.Substring(base.SelectionStart + base.SelectionLength);

                    if (!IsValid(newText, _inputType))
                        return true;
                }
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

        /// <summary>
        /// 按键事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            char c = e.KeyChar;

            // 如果是控制键, 如退格等, 则不引发验证事件
            if (Char.IsControl(c)) return;

            string newText = base.Text.Substring(0, base.SelectionStart)
                             + c.ToString() + base.Text.Substring(base.SelectionStart + base.SelectionLength);

            if (!IsValid(newText, _inputType))
            {
                e.Handled = true;
            }

            base.OnKeyPress(e);
        }

        #endregion
    }
}